<?php
/**
 * 中介者
 * 减少对象与对象之间的耦合 , 通过引入第三者解耦
 * 将 网状结构 转化为 星型接口
 *
 * 类比: QQ好友聊天 , 是多对多的结构 , 可能一个消息需要发送多次才能让自己的多个好友知道
 *         这个时候我们可以成立一个群组 , 我们只需要对着群发一次消息 , 那么这个消息就会通知到各个好友
 *
 * 理解: 设计一个中介者对象 , 将有关联的几个对象关联起来 , 由中介者去接收组件信息,并去调节调用方案
 * */
abstract class Mediator{
    abstract function componentChanged(Component $component);
}

class MediatorContact extends Mediator{
    /**
     * @var Component $componentA
     * */
    public $componentA;
    /**
     * @var Component $componentB
     * */
    public $componentB;
    /**
     * @var Component $componentC
     * */
    public $componentC;
    /**
     * @var Component $componentD
     * */
    public $componentD;
    public function componentChanged(Component $component)
    {
        if ($component === $this->componentA) {
            $this->componentB->update($component);
            $this->componentC->update($component);
            $this->componentD->update($component);
        }
    }
}
abstract class Component{
    /**
     * @var Mediator $mediator
     * */
    private $mediator;
    private $name;

    public function __construct($name,Mediator $mediator)
    {
        $this->name = $name;
        $this->mediator = $mediator;
    }

    /**
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    public function setMediator(Mediator $mediator){
        $this->mediator = $mediator;
    }

    /**
     * 组件发出通知给中介者
     * */
    public function notify(){
        var_dump($this->mediator);
        $this->mediator->componentChanged($this);
    }

    /**
     * 接收到的组件具体更新方法
     * @param Component $component
     * */
    public function update(Component $component){

    }
}

class ComponentA extends Component{
    public function update(Component $component)
    {
        echo $this->getName().'接收到来自:'.$component->getName().'的通知!'.PHP_EOL;
    }
}

class ComponentB extends Component{
    public function update(Component $component)
    {
        echo $this->getName().'接收到来自:'.$component->getName().'的通知!'.PHP_EOL;
    }
}
class ComponentC extends Component{
    public function update(Component $component)
    {
        echo $this->getName().'接收到来自:'.$component->getName().'的通知!'.PHP_EOL;
    }
}
class ComponentD extends Component{
    public function update(Component $component)
    {
        echo $this->getName().'接收到来自:'.$component->getName().'的通知!'.PHP_EOL;
    }
}

$mediator = new MediatorContact();

$component_a = new ComponentA('王大锤',$mediator);
$component_b = new ComponentB('王二锤',$mediator);
$component_c = new ComponentC('王三锤',$mediator);
$component_d = new ComponentD('王四锤',$mediator);


$mediator->componentA = $component_a;
$mediator->componentB = $component_b;
$mediator->componentC = $component_c;
$mediator->componentD = $component_d;

$component_a->notify();